package models

import (
	"bytes"
	"fmt"

	"github.com/astaxie/beego"
	"github.com/zxfonline/json"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type Mgotool struct {
	session    *mgo.Session
	Version    string
	GitVersion string
	SysInfo    string
}

var _instance *Mgotool

func GetMgotool() *Mgotool {
	url := "localhost"
	if _instance == nil {
		_instance = NewMgotool(url)
	}
	return _instance
}
func NewMgotool(url string) *Mgotool {

	var mtool = Mgotool{}
	var err error
	mtool.session, err = mgo.Dial(url)
	if err != nil {
		panic(err)
	}
	var buildInfo mgo.BuildInfo
	buildInfo, err = mtool.session.BuildInfo()
	if err != nil {
		panic(err)
	}
	mtool.Version = buildInfo.Version
	mtool.GitVersion = buildInfo.GitVersion
	mtool.SysInfo = buildInfo.SysInfo
	return &mtool
}
func (this *Mgotool) DbNames() []string {
	dbnames, err := this.session.DatabaseNames()
	if err != nil {
		panic(err)
	}
	return dbnames
}
func (this *Mgotool) CollectionNames(dbname string) []string {
	db := this.session.DB(dbname)
	rs, err := db.CollectionNames()
	if err != nil {
		panic(err)
	}
	return rs
}
func (this *Mgotool) GetJsonData(dbname, coname string, page, pagesize int) string {
	db := this.session.DB(dbname)
	c := db.C(coname)
	var q []bson.M
	var b []byte
	var buf bytes.Buffer
	var err error
	count, _ := c.Count()
	buf.WriteString(fmt.Sprintf("{\"Count\":%d,\"Data\":[", count))
	c.Find(nil).Skip((page - 1) * pagesize).Limit(pagesize).All(&q)
	isFirst := true
	for _, info := range q {
		b, err = json.Marshal(info)
		if err != nil {
			panic(err)
		}
		if !isFirst {
			buf.WriteString(",")
		} else {
			isFirst = false
		}
		buf.WriteString(string(b))
	}
	buf.WriteString("]}")
	return buf.String()
}
func (this *Mgotool) InsertCollection(dbname, coname, jsonstr string) {
	db := this.session.DB(dbname)
	c := db.C(coname)
	var f interface{}
	json.Unmarshal([]byte(jsonstr), &f)
	err := c.Insert(f)
	if err != nil {
		panic(err)
	}
}
func (this *Mgotool) GetDbStats(dbname string) interface{} {
	result := bson.M{}
	if err := this.session.DB(dbname).Run("dbstats", &result); err != nil {
		panic(err)
	}
	return result
}
func (this *Mgotool) GetServerStatus() interface{} {
	result := bson.M{}
	if err := this.session.DB("admin").Run(bson.D{{"serverStatus", 1}}, &result); err != nil {
		panic(err)
	}
	return result
}
func (this *Mgotool) DeleteCollection(dbname, coname, id string) string {
	db := this.session.DB(dbname)
	c := db.C(coname)
	objectId := bson.ObjectIdHex(id)
	err := c.Remove(bson.M{"_id": objectId})
	if err != nil {
		return err.Error() + id
	}
	return "1"
}
func (this *Mgotool) UpdateCollection(dbname, coname, jsstr string) string {
	if len(jsstr) <= 0 {
		return "jsstr is null"
	}
	db := this.session.DB(dbname)
	c := db.C(coname)
	var data bson.M
	json.Unmarshal([]byte(jsstr), &data)
	beego.Debug(jsstr)
	beego.Debug(data)
	id := data["_id"]
	if id == nil {
		return "id is null"
	}
	beego.Debug(id)
	objectId := bson.ObjectIdHex(id.(string))
	delete(data, "_id")
	err := c.Update(bson.M{"_id": objectId}, data)
	if err != nil {
		panic(err)
	}
	return "成功"
}
